/** \file MigBSPBLB.h
 *  Author: Roberto Gomes
 *  Date Created: July 3rd, 2013
 *  E-mail: rqg.gomes@gmail.com
 *
 */

/**
 *  \addtogroup CkLdb
 */

/*@{*/

#ifndef _MIGBSPLB_H_
#define _MIGBSPLB_H_

#include "CentralLB.h"
#include "LBDatabase.h"
#include "MigBSPBLB.decl.h"
#include  "cklists.h"
#include "MigBSPBLButils.h"

//margin para análise do PI na definição de Pcom
//metrica lenvantada experimentalmente
//a partir de transferência entre dois computadores em
//uma rede FastEthernet 

void CreateMigBSPBLB();


class ProcFullInfo
{
public:
	ProcFullInfo(BaseLB::LDStats *s);
	~ProcFullInfo()
	{
		delete Pfv;
	}
	int getNumProcs(){return Pfv->size();}
	void setSpeed(int i,double s){Pfv->at(i).speed = s;}
	double getSpeed(int i){return Pfv->at(i).speed;}
	void setLoad(int i,double l){Pfv->at(i).load = l;}
	double getLoad(int i){return Pfv->at(i).load;}
	void setWall(int i,double w){Pfv->at(i).wall = w;}
	double getWall(int i){return Pfv->at(i).wall;}
	void setIdle(int i,double I){Pfv->at(i).idle = I;}
	double getIdle(int i){return Pfv->at(i).idle;}
	void setTime(int i,double t){Pfv->at(i).time = t;}
	double getTime(int i){return Pfv->at(i).time;}
private:
	vector <procfullinfo> *Pfv;
};


class MigBSPBLB : public CentralLB {
public:
	MigBSPBLB(const CkLBOptions &opt);
	MigBSPBLB(CkMigrateMessage *m) : CentralLB (m) {}

	void work(LDStats *stats);
	/*Esta função é necessária para realizar a migração do LB se ocorrer*/
	void pup(PUP::er &p)
	{
		CentralLB::pup(p);
	};


private:
	double Calc_pf(ObjGraph*,double,ProcFullInfo*);
	bool MigBSPComputePM (ProcFullInfo *,ProcArray* , ObjGraph* , LDStats* );
	void MigBSPMigrate(ProcFullInfo* ,ObjGraph *, ObjGraph *);

	double Comp(ProcFullInfo*,int,Vertex*);
	double Comm(ProcInfo*,Vertex*,ObjGraph*);
	//double Comm(ProcInfo*,Vertex*,MigBSPBLBProcStatiscs*,ObjGraph*);
	double Mem(Vertex*);
	int Pjslower,Pjfaster;
	double proc_maxload;
	int i_max,j_max;
	double mean_load;
	float _alpha_ref, alpha;
	int	n_procs; //armazena o número de processadores
	int n_tasks; //armazena o número de tarefas
	float D;//limiar de detecção do desbalanceamento
	vector <pm_cadidate> pm_lst;
	vector < vector <double>* > *PM;
	vector <pm_cadidate> *PMmax;
	vector <pm_cadidate> *PMList;
	vector <vector<pm_cadidate>*> *PMListMtx;
	vector <vector<long>* > *B;
	CmiBool QueryBalanceNow(int _step);

};

#endif /* _MIGBSPLB_H_ */

/*@}*/
s